class DebugInst extends Analyser {

    _writeDebugInfoStart(code, ctx, fCtx) {
        if ((code instanceof Instruction) && code.blockId) {
            let idx = ctx.buildRelocationInfo('string', code.blockId);
            let pos = ctx.getWritingDataIdx();
            idx.idx = pos;
            ctx.pushData(new B_DBI(code, ctx, fCtx, idx));
        }
    }
    _writeDebugInfoEnd(code, ctx, fCtx, targetRegister) {
        if ((code instanceof Expr)) {
            return this._writeDebugInfoEndOfExpr(code, ctx, fCtx, targetRegister);
        } else {
            return this._writeDebugInfoEndOfInst(code, ctx, fCtx, targetRegister);
        }
    }
    static DummyRegister = {
        getTypeId() {
            return 5;
        },
        i: 0
    };
    _writeDebugInfoEndOfInst(code, ctx, fCtx, targetRegister) {
        if ((code instanceof Instruction)) {
            if (!code.blockId) {
                return targetRegister;
            }
            // let code1 = this.codeStack[0];
            // if (!(code1 && code1.blockId)) {
            //     return targetRegister;
            // }
            let idx = ctx.buildRelocationInfo('string', code.blockId);
            let pos = ctx.getWritingDataIdx();
            idx.idx = pos;
            let e = new B_ExtInfo(code, ctx, fCtx, idx);
            ctx.pushData(e);
            let b = new B_DBE(code, ctx, fCtx);
            b.register = DebugInst.DummyRegister;
            b.targetRegister = DebugInst.DummyRegister;
            ctx.pushData(b);
            return targetRegister;
        } else {
            throw Error();
        }
    }
    _writeDebugInfoEndOfExpr(code, ctx, fCtx, targetRegister) {
        if ((code instanceof Expr)) {
            if (!code.blockId) {
                return targetRegister;
            }
            // let code1 = this.codeStack[0];
            // if (!(code1 && code1.blockId)) {
            //     return targetRegister;
            // }
            let idx = ctx.buildRelocationInfo('string', code.blockId);
            let pos = ctx.getWritingDataIdx();
            idx.idx = pos;
            let e = new B_ExtInfo(code, ctx, fCtx, idx);
            ctx.pushData(e);
            let b = new B_DBE(code, ctx, fCtx);
            let reg = fCtx.getRegister(targetRegister.rtype, targetRegister.astType);
            b.register = reg;
            b.targetRegister = targetRegister;
            ctx.pushData(b);

            reg.return1 = reg.return;
            reg.return = function () {
                reg.return1();
                targetRegister.return();
            }

            return reg;
        } else {
            throw Error();
        }
    }
    visitCodeExe(inst, code, ctx, fCtx) {
        if (ctx.options.debug) {
            this._writeDebugInfoStart(code, ctx, fCtx);
        }
    }
    visitCodeEnd(code, ctx, fCtx, register) {
        if (ctx.options.debug) {
            return this._writeDebugInfoEnd(code, ctx, fCtx, register);
        }
        return register;
    }
}